/* eslint-disable @typescript-eslint/no-unused-expressions */
import { ossConfig } from '@/services/common';
import { UploadOutlined } from '@ant-design/icons';
import { Button, message, Upload } from 'antd';
import React, { useEffect, useState } from 'react';

export default function AliyunOSSUpload({
  children,
  accept,
  hadleUpLoaded,
  isShowUploaded = true,
  value,
  onChange,
  insertImage,
}: any) {
  const [OSSData, setOSSData] = useState<any>();
  // 初始化，获取 OSS 上传签名
  const init = async () => {
    try {
      const res = await ossConfig();
      setOSSData(res);
    } catch (error: any) {
      message.error(error);
    }
  };

  // 一开始就调用接口拿到 OSS 参数， 如需要文件名可在 beforeUpload 内调用 init
  useEffect(() => {
    init();
  }, []);

  // 文件上传过程中触发，直到上传完成
  const handleChange = ({ file, fileList }: any) => {
    // console.log('Aliyun OSS:', fileList);
    if (file.status === 'done') {
      hadleUpLoaded && hadleUpLoaded(file.key); // 上传成功 返回 key 值 (如果需要的话)
      insertImage && insertImage(file.url); // 上传成功 返回 上传地址 url (如果需要的话)
      message.success('上传成功');
    }
    onChange?.([...fileList]);
  };

  // 额外的上传参数
  const getExtraData = (file: any) => ({
    key: file.key,
    OSSAccessKeyId: OSSData?.accessid,
    policy: OSSData?.policy,
    Signature: OSSData?.signature,
  });

  // 选择文件之后 上传文件之前 执行
  const beforeUpload = async (file: any) => {
    if (!OSSData) return false;
    const expire = Number(OSSData.expire) * 1000;

    // 如果签名过期 重新获取
    if (expire < Date.now()) {
      await init();
    }

    const suffix = file.name.slice(file.name.lastIndexOf('.'));
    const filename = Date.now() + suffix;
    const dir = 'react/'; // 定义的上传目录
    file.key = OSSData.dir + dir + filename; // 上传用，云文件存储的key
    file.url = OSSData.host + OSSData.dir + dir + filename; // 上传完成后 做显示
    return file;
  };

  const uploadProps = {
    accept,
    name: 'file',
    fileList: value,
    action: OSSData?.host,
    onChange: handleChange,
    data: getExtraData,
    beforeUpload,
    showUploadList: isShowUploaded, // 上传后是否显示已上传列表
  };
  return (
    <Upload {...uploadProps}>
      {/* 类似vue的插槽，可以在父组件自定义内容 */}
      {children || <Button icon={<UploadOutlined />}>上传文件</Button>}
    </Upload>
  );
}
